#include <stdio.h>
#include "ohos_init.h"
#include "hi_gpio.h"
#include <unistd.h>
#include "cmsis_os2.h"
#include "lwip/netifapi.h"
#include "hi_wifi_api.h"
#include "hi_types.h"
#include <string.h>
#include "wifiiot_errno.h"
#include "wifiiot_adc.h"
#include "wifiiot_uart.h"
#include "wifi_connect.h"
#include "hi_wifi_api.h"
#include "lwip/api_shell.h"
#include <netdb.h>
#include <stdlib.h>
#include "lwip/sockets.h"


#include "bsp_usart.h"
#include "bsp_timer.h"

/* demo5
使用串口1接收串口指令控制绿灯的亮灭
led灯定时闪烁
使用按键KEY ，GPIO外部中断 控制LED灯亮灭 
STA模式连接wifi热点
指示灯显示连接状态
断线自动重新连接
STA模式UDP通信
*/


static void mymain(void);


/* 串口1收发buf */
uint8_t sendBuf[UART_BUFF_SIZE]={0};
uint8_t *sendBuf_ptr = sendBuf;

uint8_t recvBuf[UART_BUFF_SIZE]={0};
uint8_t *recvBuf_ptr = recvBuf;

/* 监听端口 */
#define _PROT_ 8888

/* 在sock_fd 进行监听 */
int sock_fd;

static const char *send_data = "Hello! I'm BearPi-HM_Nano UDP Client!\r\n";
static const char *ledon = "ledon \r\n";
static const char *ledoff = "ledoff \r\n";


/* 串口1 任务 */
static void UART_Task(void)
{

    uint32_t ret;
    uint32_t command;

    /* 串口设置 */
    WifiIotUartAttribute uart_attr = 
    {
        .baudRate = 115200,
        .dataBits = 8,
        .stopBits = 1,
        .parity = 0,
    };

    /* 初始化串口 */
    ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
    if (ret != WIFI_IOT_SUCCESS)
    {
        printf("Failed to init uart! Err code = %d\n", ret);
        return;
    }

    while (1)
    {
        /* 通过串口1接收数据 */
        UartRead(WIFI_IOT_UART_IDX_1, recvBuf_ptr, UART_BUFF_SIZE);

        //usleep(5000);
        /* 串口指令控制LED灯亮灭 */
        command = recvBuf[1];
	    command = (command <<8)  +  recvBuf[2];

        switch(command)
        {
            case LEDON:
                GreenLedOn();

                sendBuf[0] = 0x11;
                Usart_SendArray(sendBuf,10);
                break;
            
            case LEDOFF:
                GreenLedOff();
                break;

            default:
                break;

        }        
    }
}


/* 创建串口工作任务 */
static void UART_ExampleEntry(void)
{

    osThreadAttr_t attr;
    attr.name = "UART_Task";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = UART_TASK_STACK_SIZE;
    attr.priority = UART_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)UART_Task, NULL, &attr) == NULL)
    {
        printf("[ADCExample] Falied to create UART_Task!\n");
    }
}


/* 指示灯闪烁 */
static void LedTask(void)
{

    while (1)
    {
        WhiteLedOn();
        osDelay(50);
        WhiteLedOff();
        osDelay(50);
    }
}


/*entry  加入，登记 */
static void LedEntry(void)
{

    osThreadAttr_t attr;
    attr.name = "LedTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL)
    {
        printf("[LedEntry] Falied to create LedTask!\n");
    }
}



/* WIFI连接，开启UDP通信任务*/
static void UDPClientTask(void)
{  
    
    /* wifi buf指令 */
    uint32_t wifi_command;

    /* 服务器地址设置 */
    struct sockaddr_in send_addr;
    socklen_t addr_length = sizeof(send_addr);
    

    /* 客户端设置 */
    char recvBuf[512];
    struct sockaddr_in recv_addr;
    socklen_t addr_rexv_length = sizeof(recv_addr);
    

    /* wifi连接状态结构体 */
    hi_wifi_status mywifi_status; 
    

    /* 连接WIFI */
    WifiConnect("653","123456789");
    

    /* 创建socket */
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        perror("create socket failed!\r\n");
        exit(1);
    }

    /* 初始化模块自身监听的IP地址和端口，用于接收数据 */
    recv_addr.sin_family = AF_INET;
    recv_addr.sin_port = htons(_PROT_);
    recv_addr.sin_addr.s_addr = inet_addr("192.168.1.110");
    addr_rexv_length = sizeof(recv_addr);


    /* 监听模块自身的IP和PORT */
    if (bind(sock_fd, (struct sockaddr *)&recv_addr, sizeof(recv_addr)) == -1)
    {
        perror("bind is error\r\n");
        exit(1);
    }

    /* 初始化预连接的服务端地址 */
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(_PROT_);
    send_addr.sin_addr.s_addr = inet_addr("192.168.1.3");
    addr_length = sizeof(send_addr);
   

    while (1)
    {

        /* 判断WIFI连接状态 */ 
        if(hi_wifi_sta_get_connect_info(&mywifi_status)== HISI_OK &&timerOverFlag == 1 )
        {
            
            timerOverFlag = 0;
            if(mywifi_status.status == HI_WIFI_DISCONNECTED )
            {
                RedLedOff(); 
            }
            else
            {   
                RedLedOn();
            }    
        } 

        /* buf清零 */
        bzero(recvBuf, sizeof(recvBuf));

        /* 发送数据到服务远端 */
        sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length);

        /* 线程休眠一段时间 */
        //sleep(10);
        

        /* 接收服务端发送的字符串 */
        recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&recv_addr, &addr_rexv_length);

        /* 串口指令控制LED灯亮灭 */
        wifi_command = recvBuf[1];
	    wifi_command = (wifi_command <<8)  +  recvBuf[2];

        switch(wifi_command)
        {
            case LEDON:
                GreenLedOn();
                sendto(sock_fd, ledon, strlen(ledon), 0, (struct sockaddr *)&send_addr, addr_length);
                break;
            
            case LEDOFF:
                GreenLedOff();
                sendto(sock_fd, ledoff, strlen(ledoff), 0, (struct sockaddr *)&send_addr, addr_length);
                break;

            default:
                break;

        }

        /* 关闭这个 socket */
        /* 不关闭这个socket , 持续接收数据 */
        //closesocket(sock_fd);


    }
    
}



static void UDPClientDemo(void)
{
    osThreadAttr_t attr;

    attr.name = "UDPClientTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;

    if (osThreadNew((osThreadFunc_t)UDPClientTask, NULL, &attr) == NULL)
    {
        printf("[UDPClientDemo] Falied to create UDPClientTask!\n");
    }
}






/* 主函数 */
static void mymain(void)
{

    printf("=======================================\r\n");
    printf("****************WIFI_UDP***************\r\n");
    printf("=======================================\r\n");


    LED_INIT();
    GreenLedOff();
    KEY_INIT();
    UART_ExampleEntry();
    LedEntry();
    UDPClientDemo();
    Timer_INIT();

}



APP_FEATURE_INIT(mymain);
